import { IShaderBase } from "../base_frame/IShaderBase";
import { ShaderBase } from "../base_frame/ShaderBase";
import { ShaderMgr } from "../base_frame/ShaderMgr";
/**
 * 用于寻找 绘制不显示的bug  绘制时传入的索引数据类型错误导致的不显示
 */
export class Panel extends ShaderBase implements IShaderBase {

    protected readonly VS: string =
        "attribute vec4 a_Position;\n" +
        "attribute vec2 a_TexCoord;\n" +
        "uniform mat4 u_MvpMatrix;\n" +
        "varying vec2 v_TexCoord;\n" +
        "void main(){\n" +
        "   gl_Position = u_MvpMatrix * a_Position;\n" +
        "   v_TexCoord = a_TexCoord;\n" +
        "}\n";

    protected readonly FS: string =
        "#ifdef GL_ES\n" +
        "precision mediump float;\n" +
        "#endif\n" +
        "uniform sampler2D u_Sampler;\n" +
        "varying vec2 v_TexCoord;\n" +
        "void main(){\n" +
        "   gl_FragColor = vec4(1.0,0.0,0.0,1.0);\n" +
        "}\n";

    protected a_Position: number;
    protected a_TexCoord: number;


    protected count: number;
    frameBuffer: WebGLTexture;
    indiceBuffer: WebGLBuffer;
    posBuffer: any;
    coordBuffer: WebGLBuffer;
    texture: WebGLTexture;
    depthBuffer: WebGLRenderbuffer;
    init(gl: WebGL2RenderingContext | WebGLRenderingContext): void {
        //@ts-ignore
        this.program = createProgram(gl, this.VS, this.FS);
        if (!this.program) return console.error("创建渲染对象失败");
        gl.useProgram(this.program);
        this.initRef(gl);
        this.count = this.initBuffer(gl);
        this.moduleMatrix.setTranslate(1.0, 0.0, 0.0);
        this.initValue(gl);
    }

    initValue(gl: WebGL2RenderingContext | WebGLRenderingContext) {
        this.frameBuffer = gl.createFramebuffer();
        var error = () => {
            if (this.frameBuffer) gl.deleteFramebuffer(this.frameBuffer);
            if (this.texture) gl.deleteTexture(texture);
            if (this.depthBuffer) gl.deleteRenderbuffer(this.depthBuffer);
            return null;
        }
        if (!this.frameBuffer) console.error("create frame buffer fail");
        let width = 256;
        let height = 256;
        let texture = gl.createTexture();
        gl.bindTexture(gl.TEXTURE_2D, texture);
        gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
        gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
        this.texture = texture;

        this.depthBuffer = gl.createRenderbuffer();
        gl.bindRenderbuffer(gl.RENDERBUFFER, this.depthBuffer);
        gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, width, height);

        gl.bindFramebuffer(gl.FRAMEBUFFER, this.frameBuffer);
        gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0);
        gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, this.depthBuffer);

        // Check if FBO is configured correctly
        var e = gl.checkFramebufferStatus(gl.FRAMEBUFFER);
        if (gl.FRAMEBUFFER_COMPLETE !== e) {
            console.log('Frame buffer object is incomplete: ' + e.toString());
            return error();
        }

        // Unbind the buffer object
        gl.bindFramebuffer(gl.FRAMEBUFFER, null);
        gl.bindTexture(gl.TEXTURE_2D, null);
        gl.bindRenderbuffer(gl.RENDERBUFFER, null);
    }

    initBuffer(gl: WebGL2RenderingContext | WebGLRenderingContext): number {
        // Vertex coordinates
        var vertices = new Float32Array([
            1.0, 1.0, 0.0, -1.0, 1.0, 0.0, -1.0, -1.0, 0.0, 1.0, -1.0, 0.0    // v0-v1-v2-v3
        ]);

        // Texture coordinates
        var texCoords = new Float32Array([1.0, 1.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0]);

        // Indices of the vertices
        var indices = new Uint8Array([0, 1, 2, 0, 2, 3]);

        if (!(this.posBuffer = this.createBuffer(gl, this.a_Position, 3, vertices, gl.FLOAT))) return -1;
        if (!(this.coordBuffer = this.createBuffer(gl, this.a_TexCoord, 2, texCoords, gl.FLOAT))) return -1;
        let buffer = gl.createBuffer();
        gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, buffer);
        gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indices, gl.STATIC_DRAW);
        this.indiceBuffer = buffer;
        return indices.length;
    }

    protected createBuffer(gl: WebGL2RenderingContext | WebGLRenderingContext, index: number, size: number, data: any, type: number): WebGLBuffer {
        let buffer = gl.createBuffer();
        if (!buffer) return buffer;
        gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
        gl.bufferData(gl.ARRAY_BUFFER, data, gl.STREAM_DRAW);
        gl.vertexAttribPointer(index, size, type, false, 0, 0);
        gl.enableVertexAttribArray(index);
        return buffer;
    }

    initRef(gl: WebGL2RenderingContext | WebGLRenderingContext) {
        this.a_Position = gl.getAttribLocation(this.program, "a_Position");
        this.a_TexCoord = gl.getAttribLocation(this.program, "a_TexCoord");
    }

    draw(gl: WebGL2RenderingContext | WebGLRenderingContext): void {
        let canvas = ShaderMgr.canvas;
        gl.clearColor(1.0, 0.2, 0.4, 1.0);
        gl.clear(gl.COLOR_BUFFER_BIT);
        gl.viewport(0, 0, canvas.width, canvas.height);

        gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indiceBuffer);
        this.resetBuffer(gl, this.posBuffer, this.a_Position, 3, gl.FLOAT);
        this.resetBuffer(gl, this.coordBuffer, this.a_TexCoord, 2, gl.FLOAT);
        gl.drawElements(gl.TRIANGLES, this.count, gl.UNSIGNED_BYTE, 0);
    }

    protected resetBuffer(gl: WebGL2RenderingContext | WebGLRenderingContext, buffer: WebGLBuffer, index: number, size: number, type: number) {
        gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
        gl.vertexAttribPointer(index, size, type, false, 0, 0);
        gl.enableVertexAttribArray(index);
    }

    inputBlur(text: string): void {

    }

}